home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume17 / zoo2 / part06 < prev    next >
Encoding:
Internet Message Format  |  1989-02-01  |  40.5 KB

  1. Subject:  v17i069:  Zoo archive program, Part06/10
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4.  
  5. Submitted-by: Rahul Dhesi <bsu-cs!dhesi@iuvax.cs.indiana.edu>
  6. Posting-number: Volume 17, Issue 69
  7. Archive-name: zoo2/part06
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line, then unpack
  11. # it by saving it into a file and typing "sh file".  To overwrite existing
  12. # files, type "sh file -c".  You can also feed this as standard input via
  13. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  14. # will see the following message at the end:
  15. #        "End of archive 6 (of 10)."
  16. # Wrapped by rsalz@papaya.bbn.com on Thu Feb  2 18:04:02 1989
  17. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  18. if test -f 'options.doc' -a "${1}" != "-c" ; then 
  19.   echo shar: Will not clobber existing file \"'options.doc'\"
  20. else
  21. echo shar: Extracting \"'options.doc'\" \(14950 characters\)
  22. sed "s/^X//" >'options.doc' <<'END_OF_FILE'
  23. X/* @(#) options.doc 1.4 88/08/22 15:24:59 */
  24. X
  25. XDocumentation about the file options.h.
  26. X
  27. XThe file options.h defines various symbols and macros that are needed
  28. Xto ensure system-independence.  The basic philosophy is to use a
  29. Xdistinct symbol for each attribute that varies from machine to machine.
  30. XThen, for each new system, we define symbols corresponding to its
  31. Xattributes. Thus, ideally, the only place in Zoo code that we actually
  32. Xuse the name of a machine is in this file, in portable.h, and possibly in
  33. Xmachine.h and options.c.  Everywhere else in the code we only use
  34. Xnames of attributes.
  35. X
  36. XMachine names:
  37. X
  38. XMSC         Microsoft C 3.0 under MS-DOS  (not currently in use)
  39. XTURBOC      Turbo C 1.0 under MS-DOS      (works, compiled version is
  40. X                                          separately distributed)
  41. XDLC         Datalight C under MS-DOS      (not currently in use*)
  42. XFLEX        FlexDOS                       (not currently in use*)
  43. XSYS_V       UNIX System V release 2       (works)
  44. XVMS         VAX/VMS 4.4 through 4.6       (works, stream-LF files only)
  45. XBSD4_3      4.3BSD                        (works)
  46. XMCH_AMIGA   AmigaDOS Aztec/Manx C         (compiled version is separately
  47. X                                          distributed)
  48. X-----
  49. X*Mark Alexander provided me with changes to allow compilation using
  50. XFlexDOS and also Datalight's Optimum C under MSDOS but they have not
  51. Xyet been incorporated into this release.
  52. X
  53. XNOTE:  The term "zoofile" below refers to an open file of type
  54. XZOOFILE.  Currently this is defined to be equivalent to a standard
  55. Xbuffered file pointer of type "ZOOFILE *" but this may change in the
  56. Xfuture.  Dependence on exact definition of ZOOFILE is localized to a
  57. Xfew files:  options.h, portable.h, portable.c, and machine.c.
  58. X
  59. XAttributes of systems:
  60. X
  61. XCHEKDIR
  62. X   Test each supplied filename and if it is a directory or other special
  63. X   type of file, do not try to add it to an archive.  If CHEKDIR is
  64. X   defined, then machine.c must also contain function isadir() that
  65. X   tests a supplied zoofile and returns 1 if it corresponds to a
  66. X   directory or other special type of file, else 0.
  67. XCHEKUDIR
  68. X   Like CHEKDIR but use function isuadir() that tests a pathname, not
  69. X   a zoofile.  Both CHEKDIR and CHEKUDIR may be defined, if both
  70. X   functions isadir() and isuadir() are available;  in this case
  71. X   zoo code will use both and will execute slightly faster.
  72. X   (However, simultaneous definition of CHEKDIR and CHEKUDIR has
  73. X   not been tested.)
  74. XDISK_CH
  75. X   If defined, must hold the value of a character that separates a
  76. X   disk name from the rest of the pathname.  All characters up to and
  77. X   including this character will be removed from a pathname before it
  78. X   is stored in an archive.  Usually a colon (':').
  79. XEXISTS
  80. X   If defined, is assumed to be a macro that accepts a filename and
  81. X   returns an int value of 1 if the file exists and 0 if it doesn't.
  82. X   If not defined, existence of files is tested by attempting to open
  83. X   them for read or write access.
  84. XFATTR
  85. X   If defined, file attributes will be preserved.  A function
  86. X   getfattr(f) must also exist that returns the attributes of a
  87. X   zoofile f (or of a pathname f, if the symbol FATTR_FNAME is
  88. X   also defined); and a function setfattr(f, a) must exist that
  89. X   sets the attributes of a file with pathname f to the value a.
  90. X   For more details see the source code in sysv.c and bsd.c.  Currently
  91. X   the attribute value a is required to be in the zoo portable
  92. X   format.  The lowest nine bits of this format correspond to
  93. X   the **IX mode bits described for chmod(2) and these are the only
  94. X   bits currently used.
  95. XFATTR_FNAME
  96. X   If defined, and if FATTR is also defined, zoo code will
  97. X   obtain the attributes of a file by calling the function
  98. X   getfattr(f) and supplying it with filename f.  If FATTR_FNAME
  99. X   is not defined, then getfattr(f) is supplied a zoofile f.
  100. XLINT_ARGS
  101. X   Use ANSI-style function argument lists in declarations.  The symbols
  102. X   MORE, NOTHING, and VOIDPTR must also be defined.
  103. XMORE
  104. X   In function prototypes, a variable number of trailing arguments
  105. X   is specified with the symbol MORE following a trailing comma.
  106. X   For ANSI-conformant compilers, MORE will be defined to be three
  107. X   dots (...);  for others, it can be defined as necessary
  108. X   (empty string for Microsoft C 3.0).
  109. XNOTHING
  110. X   In a prototype for a function that takes no parameters, NOTHING is
  111. X   used as the parameter.  For ANSI-compatible compilers NOTHING should
  112. X   be defined to be `void'.  For other compilers it should be defined
  113. X   to be empty.
  114. XVOIDPTR
  115. X   VOIDPTR should be defined as void * if the compiler supports this
  116. X   (e.g. Turbo C), else it should be defined as char * (e.g. Microsoft
  117. X   C).
  118. XLINT
  119. X   If defined, SCCS identifier strings will not be included in the
  120. X   generated code.  This will make the code smaller and will also
  121. X   avoid complaints from lint about unused variables.  This symbol
  122. X   should be defined in the Makefile, NOT in `options.h', otherwise
  123. X   it will not be fully effective.
  124. XFOLD
  125. X   Fold filenames to lowercase.  Define this for case-insensitive filesystems
  126. XFPUTCHAR
  127. X   If defined, a library function fputchar() is assumed available
  128. X   that is like fput() but is a function, not a macro, to save
  129. X   space.  If not defined Zoo uses its own fputchar() function.
  130. XPORTABLE
  131. X   Use portable functions --- define for every system except MS-DOS
  132. XPURIFY
  133. X   When filenames are being read from standard input, ignore all
  134. X   characters begining with the first blank or tab encountered.
  135. X   This will allow filenames to be fed from a program that produces
  136. X   lines containing filenames followed by other information that
  137. X   should be ignored.  Should be defined for most non-**IX systems.
  138. XDONT_SORT
  139. X   Don't sort filename arguments -- files will be stored in the
  140. X   exact order in which names are supplied on the command line.
  141. X   Not currently used for any system, but could be used if memory
  142. X   is really tight.
  143. XNOENUM
  144. X   Compiler does not support enumerations
  145. XDUMB_ASS
  146. X   Dumb assertions must be used because the preprocessor doesn't define
  147. X   the symbols __FILE__ and __LINE__  (which hold the name of the current
  148. X   file and the number of the current line)
  149. XFNLIMIT
  150. X   Pathname length limit for this system
  151. XNEEDCTYP
  152. X   If defined, tells the code to include the header file ctype.h for
  153. X   use by character conversion macros.  If and only if NEEDCTYP is not
  154. X   defined, macros or appropriate function declarations can be put in
  155. X   portable.h.  Zoo uses isupper(), isdigit(), toascii(), and tolower().
  156. X   If NEEDCTYP is not defined, the symbol USE_ASCII can be defined to
  157. X   cause zoo to assume the ASCII character set and use its own isupper(),
  158. X   isdigit(), toascii(), and tolower() functions, possibly making the
  159. X   executable code smaller.
  160. XUSE_ASCII
  161. X   See description of NEEDCTYP.  USE_ASCII should not be defined if
  162. X   NEEDCTYP is defined, else there may be conflicts between macro
  163. X   and function names.
  164. XNIXTIME
  165. X   If defined, a function setutime() must be defined that will set the
  166. X   date and time of a file whose pathname is supplied.  If not defined,
  167. X   a function settime() must be defined that will do the same for
  168. X   a zoofile.
  169. XGETUTIME
  170. X   If defined, a function getutime() must be defined that will return
  171. X   the MS-DOS format date and time of the specified filename.  If this
  172. X   symbol is not defined, then a function gettime() must be defined
  173. X   that will do the same for a zoofile instead of a filename.
  174. XNOSIGNAL
  175. X   don't use signals because library doesn't support them
  176. XPATH_CH
  177. X   The character that separates the directory name from the filename
  178. X   in a pathname.  String value.
  179. XPATH_SEP
  180. X   The set of characters that may separate preceding directory/device
  181. X   information from the filename.  String value.
  182. XEXT_SEP is the union of PATH_SEP and the set of characters separating a
  183. X   filename extension from the rest of the filename.  String value.
  184. XEXT_CH
  185. X   Character that separates base part of filename from extension.
  186. X   Char value.
  187. XMEMSET
  188. X   If defined, a library function memset() is assumed available that
  189. X   conforms to that available under System V.  If not defined, Zoo uses
  190. X   its own memset() function.
  191. XEXT_DFLT
  192. X   default extension for archives.  String.  Currently ".zoo".
  193. XNIXFNAME
  194. X   If defined, PATH_CH, PATH_SEP, EXT_SEP, EXT_CH, and EXT_DFLT get defined
  195. X   to conform to **IX conventions and should not be separately defined
  196. XMSFNAME
  197. X   if defined, PATH_CH, PATH_SEP, EXT_SEP, EXT_CH, EXT_DFLT, and
  198. X   DISK_CH get defined to conform to MS-DOS conventions and should
  199. X   not be separately defined (not currently implemented)
  200. XFORCESLASH
  201. X   If defined any backslashes in names of files will be converted to
  202. X   slashes before the files are added to an archive.  This is useful
  203. X   for MSDOS-like systems that accept both slashes and backslashes,
  204. X   since the standard archive format allows only slashes as directory
  205. X   separators.
  206. XREN_LINK
  207. X   Rename a file by using link() followed by unlink() (e.g. Xenix, System V)
  208. XREN_NORM
  209. X   Use normal rename function:  "int rename(new, old)" (e.g. Microsoft C)
  210. XREN_REV
  211. X   Use reverse rename function:  "int rename(old, new)" (e.g. 4.3BSD,
  212. X   Turbo C).  Note:  define exactly one of REN_LINK, REN_NORM, and REN_REV.
  213. XSETMODE
  214. X   Change mode of standard output to binary when piping output, then change
  215. X   it back to text.  Macros MODE_BIN(zoofile) and MODE_TEXT(zoofile) must
  216. X   also be defined.
  217. XSETBUF
  218. X   Standard output should be set to be unbuffered so output shows up
  219. X   quickly.  Currently used only in Fiz, not in Zoo.
  220. XSPECNEXT
  221. X   If defined, a machine-dependent function nextfile() must be defined that
  222. X   will expand wildcards in a supplied pathname. If not defined, any
  223. X   wildcard expansion must have been done before the command line parameters
  224. X   are supplied to the program.  For details see the file nextfile.c.
  225. XSTRLWR
  226. X   If defined, a library function strlwr() is assumed available that converts
  227. X   a supplied string to lowercase and returns a pointer it.  If not
  228. X   defined, Zoo uses its own strlwr() function.
  229. XSTRDUP
  230. X   If defined, a library function strdup() is assumed available that
  231. X   returns a pointer to a copy of a supplied string.  If not defined,
  232. X   Zoo uses its own strdup() function.
  233. XSPECEXIT
  234. X   Custom exit handler is needed.  A function called zooexit()
  235. X   must be defined.  If SPECEXIT is not defined, zoo uses its
  236. X   own zooexit() function which simply calls exit().
  237. XSPECINIT
  238. X   If defined, zoo's main() function will call spec_init() before
  239. X   doing anything else.  Any system-specific initialization may be
  240. X   done at this point.
  241. XGETTZ
  242. X   If defined, a function gettz() must also be defined that will
  243. X   return the current timezone, in seconds west of GMT, as a long
  244. X   value.  Currently such a function is already defined in files
  245. X   bsd.c and sysv.c.  If and only if GETTZ is defined, zoo will
  246. X   store the current timezone for each file that is archived,
  247. X   and will list the timezone for each file that has one when it
  248. X   lists archive contents.
  249. XALWAYS_INT
  250. X   In function prototypes for fgetc(), fread(), and fwrite(),
  251. X   traditional practice made certain arguments int, though
  252. X   they ought to be char and unsigned respectively.  If
  253. X   ALWAYS_INT is defined, prototypes will use int only,
  254. X   else the correct types are used.
  255. XIO_MACROS
  256. X   If defined, some portable I/O functions are defined as macros,
  257. X   saving space.
  258. XZOOCOMMENT
  259. X   If defined, archive comments are fully enabled.  If not defined,
  260. X   zoo code will be smaller at the cost that archive comments will
  261. X   be listed but cannot be updated.  COMPILATION WITHOUT ZOOCOMMENT
  262. X   DEFINED HAS NOT YET BEEN TESTED.
  263. XTRACE_IO
  264. X   This is for debugging.  If defined, it will cause code to
  265. X   be compiled that will trace all archive header and directory
  266. X   entry I/O by showing it on the screen in human-readable format.
  267. X   The tracing will then occur if any Expert command given to zoo
  268. X   is preceded by a colon.  E.g., if compiled with TRACE_IO on and
  269. X   given the command "zoo :l xyz", zoo will give a directory
  270. X   listing of xyz.zoo exactly as it would with "zoo l xyz" except
  271. X   that all archive header and directory entry reads and writes
  272. X   will be shown on the screen.  The tracing code is localized
  273. X   to the files zoo.c and portable.c, so just these two files
  274. X   can be compiled afresh when TRACE_IO is turned on or switched
  275. X   off.  NOTE:  The symbol TRACE_LIST, internal to the file
  276. X   "zoolist.c", enables debugging information too.  Do not define
  277. X   both TRACE_IO and TRACE_LIST because (a) a symbol conflict will
  278. X   occur and (b) the debugging information will be duplicated.
  279. XUNBUF_IO
  280. X   If defined, some I/O is done using low-level system calls read() and
  281. X   write().  To do this, the low-level file descriptor is synchronized with
  282. X   the buffered zoofile before such I/O is done.  To do this, read(),
  283. X   write(), and lseek() system calls must be available and the fileno()
  284. X   macro must return the file descriptor for a buffered file.  This is
  285. X   not portable and should definitely not be done by most end users.  If
  286. X   UNBUF_IO is defined, also defined must be a symbol UNBUF_LIMIT with a
  287. X   numerical value that specifies the threshold over which unbuffered I/O
  288. X   should be used.  For example, if the value of UNBUF_LIMIT is 512, then
  289. X   any I/O on a zoofile that reads or writes more than 512 bytes will be
  290. X   done using read() or write() system calls.  The use of unbuffered I/O
  291. X   with a threshold in the range 512 to 1024 can enhance performance by up
  292. X   to 50%.  The corruption of data is a serious matter.  Do not define
  293. X   UNBUF_IO unless you are willing to exhaustively test the compiled code
  294. X   on your system to make sure it works, and accept full responsibility for
  295. X   any adverse consequences.  Some standard I/O libraries may attempt to
  296. X   optimize the working of fseek() on files opened for read access only,
  297. X   and cause UNBUF_IO to fail.
  298. XUNBUF_LIMIT
  299. X   Needed if and only if UNBUF_IO is defined.  Holds a numeric value.
  300. X   All I/O done in blocks that are larger than UNBUF_LIMIT bytes
  301. X   will be done unbuffered.  See UNBUF_IO.
  302. XFILTER
  303. X   If defined, code will be compiled in to enable the fc and fd
  304. X   commands (compress or decompress, reading standard input and
  305. X   writing to standard output).  These commands are useful only
  306. X   on systems that allow programs to easily act as filters.
  307. XVER_DISPLAY
  308. X   The character that will separate filenames from generation numbers
  309. X   in listings of archive contents.  Must be a single character
  310. X   in double quotes.
  311. XVER_INPUT
  312. X   The characters that will be accepted as separating filenames
  313. X   from generation numbers when typed as an argument to select
  314. X   specific files from an archive.  String value.  May include
  315. X   one or more characters;  any of them may then be typed and
  316. X   will work.
  317. XNOSTRCHR
  318. X   Although 4.3BSD as distributed from Berkeley includes strchr()
  319. X   and strrchr() library functions, 4.2BSD and similar systems
  320. X   may not.  If so, defining NOSTRCHR will cause zoo to use
  321. X   index() and rindex() instead.
  322. END_OF_FILE
  323. if test 14950 -ne `wc -c <'options.doc'`; then
  324.     echo shar: \"'options.doc'\" unpacked with wrong size!
  325. fi
  326. # end of 'options.doc'
  327. fi
  328. if test -f 'zoo.h' -a "${1}" != "-c" ; then 
  329.   echo shar: Will not clobber existing file \"'zoo.h'\"
  330. else
  331. echo shar: Extracting \"'zoo.h'\" \(10113 characters\)
  332. sed "s/^X//" >'zoo.h' <<'END_OF_FILE'
  333. X/* @(#) zoo.h 2.16 88/01/27 23:21:36 */
  334. X
  335. X/*
  336. XThe contents of this file are hereby released to the public domain.
  337. X
  338. X                           -- Rahul Dhesi 1986/11/14
  339. X*/
  340. X
  341. X
  342. X/* Global data structures and also some information about archive structure.
  343. X
  344. XAmong other things, the archive header contains:  
  345. X
  346. X(a) A text message.  In the MS-DOS version this message is terminated by
  347. Xcontrol Z.  This allows naive users to type the archive to the screen
  348. Xand see a brief but meaningful message instead of garbage.  The contents of
  349. Xthe text message are however not used by Zoo and they may be anything.  
  350. XIn particular, the text message may identify the type or archive or the
  351. Xparticular computer system it was created on.  When an archive is packed
  352. Xby any version of Zoo, the text message is changed to the text message
  353. Xused by that version.  For example, if Zoo 1.10 packs an archive created
  354. Xby Zoo 1.31, the text message changes to "Zoo 1.10 archive.".  This
  355. Xwas once considered a shortcoming, but it is now an essential feature,
  356. Xbecause packing will also update an old archiver header structure
  357. Xinto a new one.
  358. X
  359. X(b) A four-byte tag that identifies all Zoo archives.  This helps prevent
  360. Xarbitrary binary files from being treated as Zoo archives.  The tag value is
  361. Xarbitrary, but seemed to be unlikely to occur in an executable file.  The
  362. Xsame tag value is used to identify each directory entry.  
  363. X
  364. X(c) A long pointer to where in the file the archive starts.  This pointer
  365. Xis stored along with its negation for consistency checking.  It is hoped
  366. Xthat if the archive is damaged, both the pointer and its negation won't
  367. Xbe damaged and at least one would still be usable to tell us where the 
  368. Xdata begins.
  369. X
  370. X(d) A two-byte value giving the major and minor version number of the
  371. Xminimum version of Zoo that is needed to fully manipulate the archive.  
  372. XAs the archive structure is modified, this version number may increase.
  373. XCurrently version 1.71 of Zoo creates archives that may be fully manipulated
  374. Xby version 1.40 onwards.
  375. X
  376. X(e) With zoo 2.00 addtional fields have been added in the archive
  377. Xheader to store information about the archive comment and generation
  378. Xlimit.
  379. X
  380. XVersion numbering:  
  381. XThe directory entry of each file will contain the minimum version number of
  382. XZoo needed to extract that file.  As far as possible, version 1.00 of Zoo
  383. Xwill be able to extract files from future version archives.
  384. X*/
  385. X
  386. X#define H_TYPE    1                /* archive header type */
  387. X
  388. X/* Define major and minor version numbers */
  389. X#define MAJOR_VER 2        /* needed to manipulate archive */
  390. X#define MINOR_VER 0
  391. X
  392. X#define MAJOR_EXT_VER 1    /* needed to extract file */
  393. X#define MINOR_EXT_VER 0
  394. X
  395. X#define CTRL_Z 26
  396. X
  397. X/* should be 0xFDC4A7DCUL but many c compilers don't recognize UL at end */
  398. X#define ZOO_TAG ((unsigned long) 0xFDC4A7DCL) /* A random choice */
  399. X#define TEXT "ZOO 2.00 Archive.\032"   /* Header text for archive. */
  400. X#define SIZ_TEXT  20                   /* Size of header text */
  401. X
  402. X#define PATHSIZE 256                   /* Max length of pathname */
  403. X#define FNAMESIZE 13                   /* Size of DOS filename */
  404. X#define LFNAMESIZE 256                 /* Size of long filename */
  405. X#define ROOTSIZE 8                     /* Size of fname without extension */
  406. X#define EXTLEN 3                       /* Size of extension */
  407. X#define FILE_LEADER  "@)#("            /* Allowing location of file data */
  408. X#define SIZ_FLDR  5                    /* 4 chars plus null */
  409. X#define MAX_PACK 1                     /* max packing method we can handle */
  410. X#define BACKUP_EXT ".bak"              /* extension of backup file */
  411. X
  412. X#ifdef OOZ
  413. X#define FIRST_ARG 2
  414. X#endif
  415. X
  416. X#ifdef ZOO
  417. X#define FIRST_ARG 3        /* argument position of filename list */
  418. X#endif
  419. X
  420. Xtypedef unsigned char uchar;
  421. X
  422. X/* WARNING:  Static initialization in zooadd.c or zooext.c depends on the 
  423. X   order of fields in struct zoo_header */
  424. Xstruct zoo_header {
  425. X   char text[SIZ_TEXT];       /* archive header text */
  426. X   unsigned long zoo_tag;     /* identifies archives */
  427. X   long zoo_start;            /* where the archive's data starts */
  428. X   long zoo_minus;              /* for consistency checking of zoo_start */
  429. X   uchar major_ver;
  430. X   uchar minor_ver;           /* minimum version to extract all files   */
  431. X    uchar type;                        /* type of archive header */
  432. X    long acmt_pos;                    /* position of archive comment */
  433. X    unsigned int acmt_len;        /* length of archive comment */
  434. X    unsigned int vdata;            /* byte in archive;  data about versions */
  435. X};
  436. X
  437. Xstruct direntry {
  438. X   unsigned long zoo_tag;     /* tag -- redundancy check */
  439. X   uchar type;                 /* type of directory entry.  always 1 for now */
  440. X   uchar packing_method;       /* 0 = no packing, 1 = normal LZW */
  441. X   long next;                 /* pos'n of next directory entry */
  442. X   long offset;               /* position of this file */
  443. X   unsigned int date;         /* DOS format date */
  444. X   unsigned int time;         /* DOS format time */
  445. X   unsigned int file_crc;     /* CRC of this file */
  446. X   long org_size;
  447. X   long size_now;
  448. X   uchar major_ver;
  449. X   uchar minor_ver;            /* minimum version needed to extract */
  450. X   uchar deleted;              /* will be 1 if deleted, 0 if not */
  451. X   uchar struc;                /* file structure if any */
  452. X   long comment;              /* points to comment;  zero if none */
  453. X   unsigned int cmt_size;         /* length of comment, 0 if none */
  454. X   char fname[FNAMESIZE];         /* filename */
  455. X
  456. X   int var_dir_len;           /* length of variable part of dir entry */
  457. X   uchar tz;                   /* timezone where file was archived */
  458. X   unsigned int dir_crc;      /* CRC of directory entry */
  459. X
  460. X   /* fields for variable part of directory entry follow */
  461. X   uchar namlen;               /* length of long filename */
  462. X   uchar dirlen;               /* length of directory name */
  463. X   char lfname[LFNAMESIZE];   /* long filename */
  464. X   char dirname[PATHSIZE];    /* directory name */
  465. X   unsigned int system_id;    /* Filesystem ID */
  466. X    unsigned long fattr;            /* File attributes -- 24 bits */
  467. X    unsigned int vflag;            /* version flag bits -- one byte in archive */
  468. X    unsigned int version_no;    /* file version number if any */
  469. X};
  470. X
  471. X/* Values for direntry.system_id */
  472. X#define SYSID_NIX       0     /* UNIX and similar filesystems */
  473. X#define SYSID_MS        1     /* MS-DOS filesystem */
  474. X#define SYSID_PORTABLE  2     /* Portable syntax */
  475. X
  476. X/* Structure of header of small archive containing just one file */
  477. X
  478. X#define  TINYTAG     0x07FE   /* magic number */
  479. X
  480. X#ifndef PORTABLE
  481. Xstruct tiny_header {          /* one-file small archive */
  482. X   int tinytag;               /* magic number */
  483. X   char type;                 /* always 1 for now */
  484. X   char packing_method;
  485. X   unsigned int date;
  486. X   unsigned int time;
  487. X   unsigned int file_crc;
  488. X   long org_size;
  489. X   long size_now;
  490. X   char major_ver;
  491. X   char minor_ver;
  492. X   unsigned int cmt_size; /* length of comment, 0 if none */
  493. X   char fname[FNAMESIZE];     /* filename */
  494. X};
  495. X#endif /* ifndef PORTABLE */
  496. X
  497. X#define    FIXED_OFFSET 34        /* zoo_start in old archives */
  498. X#define    MINZOOHSIZ 34            /* minimum size of archive header */
  499. X#define  SIZ_ZOOH  42            /* length of current archive header */
  500. X
  501. X/* offsets of items within the canonical zoo archive header */
  502. X#define  TEXT_I    0           /* text in header */
  503. X#define  ZTAG_I    20          /* zoo tag */
  504. X#define  ZST_I     24          /* start offset */
  505. X#define  ZSTM_I    28          /* negative of start offset */
  506. X#define  MAJV_I    32          /* major version */
  507. X#define  MINV_I    33          /* minor version */
  508. X#define    HTYPE_I     34            /* archive header type */
  509. X#define    ACMTPOS_I 35            /* position of archive comment */
  510. X#define    ACMTLEN_I 39            /* length of archive comment */
  511. X#define    HVDATA_I     41            /* version data */
  512. X
  513. X/* offsets of items within the canonical directory entry structure */
  514. X#define  SIZ_DIR  51          /* length of type 1 directory entry */
  515. X#define  SIZ_DIRL 56          /* length of type 2 directory entry */
  516. X#define  DTAG_I   0           /* tag within directory entry */
  517. X#define  DTYP_I   4           /* type of directory entry */
  518. X#define  PKM_I    5           /* packing method */
  519. X#define  NXT_I    6           /* pos'n of next directory entry */
  520. X#define  OFS_I    10          /* position (offset) of this file */
  521. X#define  DAT_I    14          /* DOS format date */
  522. X#define  TIM_I    16          /* DOS format time */
  523. X#define  CRC_I    18          /* CRC of this file */
  524. X#define  ORGS_I   20          /* original size */
  525. X#define  SIZNOW_I 24          /* size now */
  526. X#define  DMAJ_I   28          /* major version number */
  527. X#define  DMIN_I   29          /* minor version number */
  528. X#define  DEL_I    30          /* deleted or not */
  529. X#define  STRUC_I  31          /* file structure */
  530. X#define  CMT_I    32          /* comment [offset] */
  531. X#define  CMTSIZ_I 36          /* comment size */
  532. X#define  FNAME_I  38          /* filename */
  533. X#define  VARDIRLEN_I  51      /* length of var. direntry */
  534. X#define  TZ_I     53          /* timezone */
  535. X#define  DCRC_I   54          /* CRC of directory entry */
  536. X
  537. X#define  FNM_SIZ  13          /* size of stored filename */
  538. X
  539. X/* Offsets within variable part of directory entry */
  540. X#define  NAMLEN_I   (SIZ_DIRL + 0)
  541. X#define  DIRLEN_I   (SIZ_DIRL + 1)
  542. X#define  LFNAME_I   (SIZ_DIRL + 2)
  543. X#define  DIRNAME_I  LFNAME_I  /* plus length of filename */
  544. X
  545. X/*
  546. XTotal size of fixed plus variable directory recognized currently:
  547. XOne byte each for dirlen and namlen, 256 each for long filename and
  548. Xdirectory name, 2 for system id, 3 for file attributes, 1 for 
  549. Xversion flag, 2 for version number, plus a fudge factor of 5.
  550. X*/
  551. X#define  MAXDIRSIZE  (SIZ_DIRL+1+1+256+256+2+3+1+2+5)
  552. X
  553. X/* Value used to stuff into timezone field if it is not known */
  554. X#define  NO_TZ    127
  555. X
  556. X/* Value for no file attributes */
  557. X#define    NO_FATTR        0L
  558. X
  559. X/* version flag bits */
  560. X#define    VFL_ON    0x80        /* enable version numbering */
  561. X#define    VFL_GEN    0x0f        /* generation count */
  562. X#define    VFL_LAST 0x40        /* last generation of this file */
  563. X
  564. X/* default generation value for archive */
  565. X#define    GEN_DEFAULT            1
  566. X/* max generation count, file or archive */
  567. X#define    MAXGEN                0x0f
  568. X/* version mask to prune down to correct size on large-word machines */
  569. X#define VER_MASK                0xffff
  570. END_OF_FILE
  571. if test 10113 -ne `wc -c <'zoo.h'`; then
  572.     echo shar: \"'zoo.h'\" unpacked with wrong size!
  573. fi
  574. # end of 'zoo.h'
  575. fi
  576. if test -f 'zoopack.c' -a "${1}" != "-c" ; then 
  577.   echo shar: Will not clobber existing file \"'zoopack.c'\"
  578. else
  579. echo shar: Extracting \"'zoopack.c'\" \(13207 characters\)
  580. sed "s/^X//" >'zoopack.c' <<'END_OF_FILE'
  581. X#ifndef LINT
  582. X/* @(#) zoopack.c 2.16 88/08/22 15:51:20 */
  583. Xstatic char sccsid[]="@(#) zoopack.c 2.16 88/08/22 15:51:20";
  584. X#endif /* LINT */
  585. X
  586. X/*
  587. XCopyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  588. X(C) Copyright 1988 Rahul Dhesi -- All rights reserved
  589. X*/
  590. X#include "options.h"
  591. X/* Packs an archive.  The sequence is:
  592. X   1. Copy all files from current archive to new one.
  593. X   2. If the user didn't want a backup, delete the old archive
  594. X      else rename it to same name with extension of .BAK.
  595. X   3. Rename temporary archive to old name.
  596. X*/
  597. X
  598. X/* define this to make packing noisless */
  599. X#define QUIETPACK 1
  600. X
  601. X
  602. X#include "portable.h"
  603. X#include "zooio.h"
  604. X#include "various.h"
  605. X#include "zoo.h"
  606. X#include "zoofns.h"
  607. X#include "errors.i"
  608. X#ifndef NOSIGNAL
  609. X#include <signal.h>
  610. X#endif
  611. X
  612. X#ifdef LINT_ARGS
  613. Xchar *mktemp (char *);
  614. X#else
  615. Xchar *mktemp ();
  616. X#endif
  617. X
  618. X
  619. Xstruct zoo_header zoo_header = {
  620. X   TEXT,
  621. X   ZOO_TAG,
  622. X   (long) SIZ_ZOOH,
  623. X   (long) (-SIZ_ZOOH),
  624. X   MAJOR_VER,
  625. X   MINOR_VER,
  626. X    H_TYPE,
  627. X    0L,                        /* comment position */
  628. X    0,                            /* comment length */
  629. X    GEN_DEFAULT                /* generations */
  630. X};
  631. Xchar file_leader[] = FILE_LEADER;
  632. Xextern int quiet;
  633. Xint break_hit;
  634. X
  635. X#ifdef LINT_ARGS
  636. Xint ver_too_high (struct zoo_header *);
  637. X#else
  638. Xint ver_too_high();
  639. X#endif
  640. X
  641. Xvoid zoopack(zoo_path, option)
  642. Xchar *zoo_path, *option;
  643. X{
  644. Xchar temp_file[PATHSIZE];
  645. Xstatic char xes[]="XXXXXX";               /* template for temp file */
  646. X
  647. X#ifndef NOSIGNAL
  648. Xint (*oldsignal)();
  649. X#endif
  650. Xregister ZOOFILE zoo_file;                /* archive */
  651. XZOOFILE new_file;                         /* destination archive */
  652. Xlong next_ptr;                            /* pointer to within archive */
  653. Xlong new_dir_pos;                         /* ditto */
  654. Xstruct direntry direntry;                 /* directory entry */
  655. Xstruct zoo_header old_zoo_header;         /* just for reading old header */
  656. Xint status;                               /* error status */
  657. Xint nobackup = 0;                         /* keep backup */
  658. Xint force = 0;                            /* force overwrite of old backup */
  659. Xint extcount = 0;                         /* how many files moved */
  660. Xchar backup_name[PATHSIZE];               /* name of backup */
  661. Xint bad_header = 0;                       /* if archive has bad header */
  662. Xint latest_date = 0;                      /* latest date on any file moved */
  663. Xint latest_time = 0;                      /*  ...likewise */
  664. Xint curr_dir = 0;                                    /* create backup in curr dir */
  665. Xstatic char partial_msg[] =
  666. X   "Partially packed archive left in %s.\n";
  667. X
  668. X#ifdef FATTR
  669. Xunsigned long zoofattr;                            /* zoo archive protection */
  670. Xint setfattr PARMS ((char *, unsigned long));
  671. Xunsigned long getfattr                            /* params below */
  672. X# ifdef FATTR_FNAME
  673. X  PARMS ((char *));
  674. X# else
  675. X  PARMS ((ZOOFILE));
  676. X# endif /* FATTR_FNAME */
  677. X#endif /* FATTR */
  678. X
  679. Xwhile (*option) {
  680. X   switch (*option) {
  681. X      case 'P': force++; break;
  682. X      case 'E': nobackup++; break;
  683. X      case 'q': quiet++; break;
  684. X        case '.': curr_dir++; break;
  685. X      default:
  686. X         prterror ('f', inv_option, *option);
  687. X   }
  688. X   option++;
  689. X}
  690. Xif (force == 1)         /* force only if P was doubled */
  691. X   force--;
  692. X
  693. Xzoo_path = addext (zoo_path, EXT_DFLT);      /* add default extension */
  694. X
  695. X/* Create a backup name by replacing any extension by backup extension. */
  696. Xstrcpy (backup_name, zoo_path);
  697. X{
  698. X   char *temp;
  699. X   if ((temp = strrchr (backup_name,EXT_CH)) != 0)  /* if dot found */
  700. X      strcpy (temp, BACKUP_EXT);                /* replace old extension */
  701. X   else
  702. X      strcat (backup_name, BACKUP_EXT);         /* else just append */
  703. X}
  704. X
  705. X/*
  706. XOpen original archive for read-write access.  Although we will only
  707. Xread from it and never write to it, we want to avoid packing an
  708. Xarchive that is read-only, since presumably the user didn't want
  709. Xto risk changing it in any way.
  710. X*/
  711. Xzoo_file = zooopen(zoo_path, Z_RDWR);
  712. X
  713. Xif (zoo_file == NOFILE)
  714. X   prterror ('f', could_not_open, zoo_path);
  715. X
  716. X/* If possible, save protection code of old archive for propagation to new */
  717. X#ifdef FATTR
  718. X# ifdef FATTR_FNAME
  719. X   zoofattr = getfattr (zoo_path);
  720. X# else
  721. X   zoofattr = getfattr (zoo_file);
  722. X# endif /* FATTR_FNAME */
  723. X#endif /* FATTR */
  724. X
  725. X/* Read the header of the old archive. */
  726. Xfrd_zooh(&old_zoo_header, zoo_file);
  727. X
  728. Xif ((old_zoo_header.zoo_start + old_zoo_header.zoo_minus) != 0L) {
  729. X   prterror ('w', failed_consistency);
  730. X   ++bad_header;                    /* remember for future error message */
  731. X}
  732. X
  733. X/* Refuse to pack it if its version number is higher than we can accept */
  734. Xif (ver_too_high (&old_zoo_header))
  735. X   prterror ('f', wrong_version, old_zoo_header.major_ver,
  736. X                                    old_zoo_header.minor_ver);
  737. X
  738. X/* Now see if the archive already exists with the backup extension.  If so,
  739. X   give an error message and abort.  However, we skip this test if the user
  740. X   specified overwriting the backup */
  741. X
  742. Xif (!force) {
  743. X   if (exists (backup_name))
  744. X      prterror ('f', "File %s already exists.  Delete it or use PP option.\n",
  745. X                      backup_name);
  746. X}
  747. X
  748. X/*
  749. XOpen the new archive by a temporary name.  If not otherwise specified,
  750. Xwe open the new archive in the same directory as the original.  But if
  751. Xthe curr_dir switch was given, we just put XXXXXX into temp_file.
  752. X*/
  753. Xif (!curr_dir) {
  754. X    strcpy (temp_file, zoo_path);          /* original archive name */
  755. X    *nameptr (temp_file) = '\0';           /* ... minus original filename */
  756. X    strcat (temp_file, xes);               /* ... plus XXXXXX */
  757. X} else {
  758. X   strcpy (temp_file, xes);
  759. X}
  760. Xmktemp (temp_file);                    /* ... and make unique */
  761. Xnew_file = zoocreate (temp_file);
  762. Xif (new_file == NOFILE)
  763. X   prterror ('f', "Could not create temporary file %s.\n", temp_file);
  764. X
  765. X/*
  766. XIf old_zoo_header greater than type 0, we update zoo_header as follows:  
  767. Xnew archive comment will be just after archive header;  zoo_start will 
  768. Xpoint to just beyond archive comment.  But if old_zoo_header is of 
  769. Xtype 0, we leave zoo_header unchanged.  However, we always 
  770. Xunconditionally update the header type to be type H_TYPE.  
  771. X(Note:  zoo_header.type is initialized to H_TYPE in the
  772. Xglobal declaration of zoo_header.)
  773. X*/
  774. Xif (old_zoo_header.type > 0) {
  775. X    zoo_header.zoo_start = SIZ_ZOOH + old_zoo_header.acmt_len;
  776. X    zoo_header.zoo_minus = -zoo_header.zoo_start;
  777. X    zoo_header.acmt_pos = SIZ_ZOOH;    /* new comment just after header */
  778. X    zoo_header.acmt_len = old_zoo_header.acmt_len;
  779. X    zoo_header.vdata      = old_zoo_header.vdata;
  780. X} else /* keep generations off if using old format archive */
  781. X    zoo_header.vdata &=  (~VFL_ON);
  782. X
  783. X/* Write the header of the new archive, updated with our own data */
  784. Xfwr_zooh (&zoo_header, new_file);
  785. X
  786. X/* copy archive comment */
  787. Xif (old_zoo_header.acmt_len != 0) {
  788. X    zooseek (zoo_file, old_zoo_header.acmt_pos, 0);    /* find archive comment */
  789. X    getfile (zoo_file, new_file, (long) zoo_header.acmt_len, 0); /* copy it */
  790. X}
  791. X
  792. X/* WARNING: CHECK FOR SEEK BEYOND END OF FILE */
  793. Xzooseek (new_file, zoo_header.zoo_start, 0);       /* position to add files */
  794. X
  795. Xzooseek (zoo_file, old_zoo_header.zoo_start, 0); /* seek to where data begins */
  796. X
  797. X/* Now we loop through the old archive's files and add each to the new
  798. Xarchive.  The only changes needed are to update the .next and .offset
  799. Xfields of the directory entry. */
  800. X
  801. Xwhile (1) {
  802. X   frd_dir(&direntry, zoo_file);
  803. X   if (direntry.zoo_tag != ZOO_TAG) {
  804. X      long currpos, zoolength;
  805. X      prterror ('F', bad_directory);
  806. X      if (bad_header) {    /* bad headers means don't save temp file */
  807. X         zooclose (new_file);
  808. X         unlink (temp_file);
  809. X      } else {
  810. X         writenull (new_file, MAXDIRSIZE);    /* write final null entry */
  811. X         printf (partial_msg, temp_file);
  812. X         if ((currpos = ftell (zoo_file)) != -1L)
  813. X            if (zooseek (zoo_file, 0L, 2) == 0)
  814. X               if ((zoolength = ftell (zoo_file)) != -1L)
  815. X                  printf (cant_process, zoolength - currpos);
  816. X      }
  817. X      zooexit (1);
  818. X   }
  819. X   if (direntry.next == 0L) {                /* END OF CHAIN */
  820. X      break;                                 /* EXIT on end of chain */
  821. X   }
  822. X   next_ptr = direntry.next;                 /* ptr to next dir entry */
  823. X
  824. X   if (!direntry.deleted) {
  825. X#ifdef QUIETPACK
  826. X/* nothing */
  827. X#else
  828. X      prterror ('m', "%-14s -- ",
  829. X         direntry.namlen > 0 ? direntry.lfname : direntry.fname);
  830. X#endif
  831. X
  832. X      if (zooseek (zoo_file, direntry.offset, 0) == -1L) {
  833. X         prterror ('f', "Could not seek to file data.\n");
  834. X      } else {
  835. X         extcount++;          /* update count of files extracted */
  836. X
  837. X         /* write a directory entry for this file */
  838. X         new_dir_pos = zootell (new_file); /* new direntry pos in new archive */
  839. X
  840. X         /*
  841. X         Write a null directory entry to preserve integrity in case of
  842. X         program being interrupted.  Note:  I don't think it is
  843. X         necessary to save direntry.next but I haven't checked.
  844. X         */
  845. X         {
  846. X            long oldnext;
  847. X            oldnext = direntry.next;
  848. X            direntry.next = 0L;
  849. X            fwr_dir(&direntry, new_file);
  850. X            direntry.next = oldnext;
  851. X         }
  852. X
  853. X         zooseek (zoo_file, direntry.offset, 0);  /* where to start copying */
  854. X         /* Write file leader and remember position of new file data */
  855. X         zoowrite (new_file, file_leader, SIZ_FLDR);
  856. X         direntry.offset = zootell (new_file);
  857. X         status = getfile (zoo_file, new_file, direntry.size_now, 0);
  858. X         /* if no error copy any comment attached to file */
  859. X         if (status == 0 && direntry.cmt_size != 0) {
  860. X            zooseek (zoo_file, direntry.comment, 0);  /* seek to old comment  */
  861. X            direntry.comment = zootell (new_file); /* location of new comment */
  862. X            status = getfile (zoo_file, new_file,
  863. X                                 (long) direntry.cmt_size, 0);
  864. X         }
  865. X
  866. X         if (status != 0) {
  867. X            if (status == 1) {
  868. X               memerr();
  869. X            } else
  870. X               if (status == 2 || status == 3) {
  871. X                  prterror ('F', disk_full);
  872. X                  printf (partial_msg, temp_file);
  873. X                  zooexit (1);
  874. X               } else
  875. X                  prterror ('f', internal_error);
  876. X         } else {
  877. X            if (latest_date < direntry.date ||
  878. X                     (latest_date == direntry.date &&
  879. X                           latest_time < direntry.time))  {
  880. X               latest_date = direntry.date;
  881. X               latest_time = direntry.time;
  882. X            }
  883. X         }
  884. X         direntry.next = zootell (new_file);
  885. X         zooseek (new_file, new_dir_pos, 0);  /* position to write direntry */
  886. X
  887. X         break_hit = 0;
  888. X#ifndef NOSIGNAL
  889. X         oldsignal = signal (SIGINT, SIG_IGN);
  890. X         if (oldsignal != SIG_IGN)
  891. X            signal (SIGINT, handle_break);
  892. X#endif
  893. X
  894. X            /* Bug fix thanks to Mark Alexander */
  895. X         if (fwr_dir (&direntry, new_file) != -1 &&
  896. X            zoowrite (new_file, file_leader, SIZ_FLDR) == SIZ_FLDR) {
  897. X#ifdef QUIETPACK
  898. X            /* prterror ('M', "."); */ ;
  899. X#else
  900. X            prterror ('M', "moved\n");
  901. X#endif
  902. X         } else
  903. X            prterror ('f', "Write to temporary packed archive %s failed.\n", temp_file);
  904. X#ifndef NOSIGNAL
  905. X         signal (SIGINT, oldsignal);
  906. X#endif
  907. X         if (break_hit)
  908. X            zooexit (1);
  909. X         zooseek (new_file, direntry.next, 0);  /* back to end of new archive */
  910. X      }  /* end if (lseek ... */
  911. X   } /* end if (!direntry.deleted) */
  912. X
  913. Xzooseek (zoo_file, next_ptr, 0);   /* ..seek to next dir entry */
  914. X} /* end while */
  915. X
  916. Xzooclose (zoo_file);
  917. X
  918. X/* write a final null entry */
  919. Xwritenull (new_file, MAXDIRSIZE);
  920. X
  921. X#ifdef NIXTIME
  922. Xzooclose (new_file);
  923. Xsetutime (temp_file, latest_date, latest_time);
  924. X#else
  925. Xsettime (new_file, latest_date, latest_time);    /* adjust its time */
  926. Xzooclose (new_file);
  927. X#endif
  928. X
  929. X/* Important note:  At this point, it is assumed that the archive was
  930. X   packed and written to a new file without error.  If control reaches
  931. X   here without the new archive having been written properly, then
  932. X   loss of data due to deletion of the original file could occur.  In
  933. X   other words, if something went wrong, execution MUST NOT reach here. */
  934. X
  935. Xif (extcount == 0) {
  936. X   unlink (temp_file);
  937. X   prterror ('m', "No files moved.\n");
  938. X} else {
  939. X   /* (a) if user requested, delete original, else rename it to
  940. X   *.bak.  (b) rename temp file to same base name as zoo_file. */
  941. X
  942. X#ifdef QUIETPACK
  943. X   /* prterror('M', "\n"); */
  944. X#endif
  945. X
  946. X   unlink (backup_name);    /* remove any previous backup in any case */
  947. X   if (nobackup)
  948. X      unlink (zoo_path);
  949. X   else
  950. X      chname (backup_name, zoo_path);
  951. X
  952. X    /* if we are packing into current directory, we will rename temp file
  953. X        to same basename but without the preceding pathname */
  954. X    if (curr_dir)
  955. X        zoo_path = nameptr (zoo_path);        /* strip pathname */
  956. X
  957. X
  958. X   if (chname (zoo_path, temp_file)) {
  959. X      prterror ('w', "Renaming error.  Packed archive is now in %s.\n", temp_file);
  960. X      zooexit (1);
  961. X   }
  962. X
  963. X/*
  964. XSet protection on packed archive -- after renaming, since some
  965. XOSs might not allow renaming of read-only files
  966. X*/
  967. X#ifdef FATTR
  968. X    setfattr (zoo_path, zoofattr);
  969. X#endif /* FATTR */
  970. X
  971. X} /* end if */
  972. X
  973. X} /* end zoopack() */
  974. X
  975. X/* handle_break() */
  976. X/* Sets break_hit to 1 when called */
  977. Xint handle_break()
  978. X{
  979. X#ifndef NOSIGNAL
  980. X   signal (SIGINT, SIG_IGN);     /* ignore future control ^Cs for now */
  981. X   break_hit = 1;
  982. X#endif
  983. X}
  984. END_OF_FILE
  985. if test 13207 -ne `wc -c <'zoopack.c'`; then
  986.     echo shar: \"'zoopack.c'\" unpacked with wrong size!
  987. fi
  988. # end of 'zoopack.c'
  989. fi
  990. echo shar: End of archive 6 \(of 10\).
  991. cp /dev/null ark6isdone
  992. MISSING=""
  993. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  994.     if test ! -f ark${I}isdone ; then
  995.     MISSING="${MISSING} ${I}"
  996.     fi
  997. done
  998. if test "${MISSING}" = "" ; then
  999.     echo You have unpacked all 10 archives.
  1000.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1001. else
  1002.     echo You still need to unpack the following archives:
  1003.     echo "        " ${MISSING}
  1004. fi
  1005. ##  End of shell archive.
  1006. exit 0
  1007.